#pragma once

#include <stddef.h>
#include <stdbool.h>
#include <libs/klibc.h>
#include <stdint.h>
#include <arch/arch.h>
#include <drivers/fdt/fdt_context.h>

//------------------------------------
// 通用 PCI/PCIe 配置寄存器偏移
//------------------------------------
#define PCI_CONF_VENDOR   0x00  // Vendor ID
#define PCI_CONF_DEVICE   0x02  // Device ID
#define PCI_CONF_COMMAND  0x04  // Command
#define PCI_CONF_STATUS   0x06  // Status
#define PCI_CONF_REVISION 0x08  // Revision ID

//------------------------------------
// 通用宏定义
//------------------------------------
#define PCI_DEVICE_MAX 256
#define PCI_MCFG_MAX_ENTRIES_LEN 1024

//------------------------------------
// PCIe BAR 地址描述
//------------------------------------
typedef struct {
    uint64_t address;
    uint64_t size;
    bool mmio;
} pci_bar_t;

//------------------------------------
// 访问操作接口（不同架构不同实现）
//------------------------------------
typedef struct {
    uint32_t (*read)(uint32_t bus, uint32_t dev, uint32_t func,
                     uint32_t seg, uint32_t offset);
    void (*write)(uint32_t bus, uint32_t dev, uint32_t func,
                  uint32_t seg, uint32_t offset, uint32_t value);
} pci_device_op_t;

//------------------------------------
// PCI 设备结构体
//------------------------------------
typedef struct {
    const char *name;
    uint32_t class_code;
    uint8_t header_type;

    uint16_t vendor_id;
    uint16_t device_id;
    uint16_t segment;
    uint8_t bus;
    uint8_t slot;
    uint8_t func;

    pci_bar_t bars[6];
    uint32_t capability_point;

    pci_device_op_t *op;
} pci_device_t;

//------------------------------------
// 全局设备表
//------------------------------------
extern pci_device_t *pci_devices[PCI_DEVICE_MAX];

//------------------------------------
// 通用函数声明
//------------------------------------
uint32_t segment_bus_device_functon_to_pci_address(
    uint16_t segment, uint8_t bus, uint8_t device, uint8_t function);

uint64_t get_mmio_address(uint32_t pci_address, uint16_t offset);

uint32_t pci_read(uint32_t bus, uint32_t dev, uint32_t func,
                  uint32_t seg, uint32_t offset);

void pci_write(uint32_t bus, uint32_t dev, uint32_t func,
               uint32_t seg, uint32_t offset, uint32_t value);

uint32_t pci_enumerate_capability_list(pci_device_t *pci_dev, uint32_t cap_type);

const char *pci_classname(uint32_t classcode);
pci_device_t *pci_find_vid_did(uint16_t vendor_id, uint16_t device_id);
pci_device_t *pci_find_class(uint32_t class_code);

//------------------------------------
// 初始化接口（架构相关）
//------------------------------------
void pci_init();

#if defined(__x86_64__)
//---------------- x86_64 部分 ----------------
#include <arch/x64/acpi/acpi.h>

void mcfg_addr_to_entries(MCFG *mcfg, MCFG_ENTRY **entries, uint64_t *len);
void pcie_setup(MCFG *mcfg);

#else
//---------------- RISC-V 部分 ----------------

// RISC-V 使用 ECAM (MMIO) 访问 PCI 配置空间
void pci_set_ecam_base(uint64_t base, uint8_t start_bus,
                       uint8_t end_bus, uint16_t segment);
void pci_init_from_fdt();

// （未来）可用于 FDT 初始化，例如：
// void pci_init_from_fdt(const void *fdt);

#endif
